classdef MOEAFDVA < ALGORITHM
% <multi> <real/integer> <large>
% Multi-objective evolutionary algorithm based on decision variable
% analyses

%------------------------------- Reference --------------------------------
% X. Ma, F. Liu, Y. Qi, X. Wang, L. Li, L. Jiao, M. Yin, and M. Gong, A
% multiobjective evolutionary algorithm based on decision variable analyses
% for multiobjective optimization problems with large-scale variables, IEEE
% Transactions Evolutionary Computation, 2016, 20(2): 275-298.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2024 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    methods
        function main(Algorithm,Problem)
            %% Parameter setting
            % [RefV,Problem.N] = UniformPoint(Problem.N,Problem.M);
            %% Control variable analysis
            [ConverIndexes,DiverIndexes] = variable_analysis(Problem);
            
            %% Dividing distance variables based on two variable analyses
            tic; % 开始计时
            Subcomponents = group_dec(Problem,ConverIndexes);
            elapsedTime = toc; % 结束计时并返回运行时间
            fprintf('Function execution time: %.4f seconds\n', elapsedTime);
            Population = Algorithm.init_population(Problem,ConverIndexes,DiverIndexes);
            % Population = Problem.Initialization(Problem.N);
            Neighbour = Algorithm.calc_neighbours(Population, Problem, DiverIndexes);  
            %% Subcomponent optimization
            while Algorithm.NotTerminated(Population)
                % GuidingSolution = DirectedSampling(Problem,Population,30,10,RefV);
                % Population = EnvironmentalSelection([GuidingSolution, Population],Problem.N);
                for i = 1 : length(Subcomponents)
                    drawnow('limitrate');     
                    Population = SubcomponentOptimizer(Problem,Population,Neighbour,Subcomponents{i});
                end
            end
        end
    end
      methods(Static)
        function Neighbour = calc_neighbours(Population, Problem, DiverIndexes)
            PopDec = Population.decs;
            Dis    = pdist2(PopDec(:,DiverIndexes),PopDec(:,DiverIndexes));
            Dis(logical(eye(length(Dis)))) = inf;
            [~,Neighbour] = sort(Dis,2);
            Neighbour     = Neighbour(:,1:ceil(Problem.N/10));
        end
        
        function Population=init_population(Problem,ConverIndexes,DiverIndexes)
            PopDec = zeros(Problem.N,Problem.D);
            if sum(DiverIndexes) == 1
                PopDec(:,DiverIndexes) = (0:Problem.N-1)/(Problem.N-1);
            elseif sum(DiverIndexes) > 4
                PopDec(:,DiverIndexes) = rand(Problem.N,sum(DiverIndexes));
            else
                PopDec(:,DiverIndexes) = UDall(Problem.N,sum(DiverIndexes));
            end
            % Randomly generate the distance variables
            PopDec(:,ConverIndexes) = rand(Problem.N,sum(ConverIndexes));
             % Generate the initial population
            PopDec     = PopDec.*repmat(Problem.upper-Problem.lower,Problem.N,1) + repmat(Problem.lower,Problem.N,1);
            Population = Problem.Evaluation(PopDec);
        end
      end
end